#ifndef __INA226_H_
#define __INA226_H_

#include "swiic.h"

typedef enum INA226_AVERAGES {
    AVERAGE_1       = 0x0000, 
    AVERAGE_4       = 0x0200,
    AVERAGE_16      = 0x0400,
    AVERAGE_64      = 0x0600,
    AVERAGE_128     = 0x0800,
    AVERAGE_256     = 0x0A00,
    AVERAGE_512     = 0x0C00,
    AVERAGE_1024    = 0x0E00
} averageMode;

typedef enum INA226_CONV_TIME { // Conversion time in microseconds
    CONV_TIME_140 = 0,
    CONV_TIME_204 ,
    CONV_TIME_332 ,
    CONV_TIME_588 ,
    CONV_TIME_1100,
    CONV_TIME_2116,
    CONV_TIME_4156,
    CONV_TIME_8244,
} convTime;

typedef enum INA226_MEASURE_MODE {
#ifndef INA226_WE_COMPATIBILITY_MODE_
    POWER_DOWN      = 0,
    TRIGGERED       = 3,
    CONTINUOUS      = 7
#else
    INA226_POWER_DOWN   = 0,
    INA226_TRIGGERED    = 3,
    INA226_CONTINUOUS   = 7
#endif
} INA226_measureMode;

typedef enum INA226_ALERT_TYPE {
    SHUNT_OVER    = 0x8000,
    SHUNT_UNDER   = 0x4000,
    BUS_OVER      = 0x2000,
    BUS_UNDER     = 0x1000,
    POWER_OVER    = 0x0800,
    CURRENT_OVER  = 0xFFFE,
    CURRENT_UNDER = 0xFFFF,
} alertType;

typedef enum INA226_CURRENT_RANGE { // Deprecated, but left for downward compatibility
    MA_400,
    MA_800
} currentRange;

typedef struct {
    averageMode deviceAverages;
    convTime deviceConvTime;
    INA226_measureMode deviceMeasureMode;
    currentRange deviceCurrentRange;
    alertType deviceAlertType; 
    _Bool overflow;
    _Bool convAlert;
    _Bool limitAlert;
} INA226_WE;

extern INA226_WE ina;

#define INA226_ADDRESS         0x40
#define INA226_CONF_REG        0x00
#define INA226_SHUNT_REG       0x01
#define INA226_BUS_REG         0x02
#define INA226_PWR_REG         0x03
#define INA226_CURRENT_REG     0x04
#define INA226_CAL_REG         0x05
#define INA226_MASK_EN_REG     0x06
#define INA226_ALERT_LIMIT_REG 0x07
#define INA226_MAN_ID_REG      0xFE
#define INA226_ID_REG          0xFF

#define INA226_RST        0x8000
#define INA226_AFF        0x0010
#define INA226_CVRF       0x0008
#define INA226_OVF        0x0004
#define INA226_ALERT_POL  0x0002
#define INA226_LATCH_EN   0x0001

_Bool INA226_WE_init(void);
void INA226_WE_reset_INA226(void);
void INA226_WE_setCorrectionFactor( float corr);
void INA226_WE_setAverage( averageMode averages);
void INA226_WE_setConversionTime( convTime shuntConvTime, convTime busConvTime);
void INA226_WE_setMeasureMode( INA226_measureMode mode);
void INA226_WE_setCurrentRange( currentRange range);
void INA226_WE_setResistorRange( float resistor, float range);
float INA226_WE_getShuntVoltage_mV(void);
float INA226_WE_getShuntVoltage_V(void);
float INA226_WE_getBusVoltage_V(void);
float INA226_WE_getCurrent_mA(void);
float INA226_WE_getCurrent_A(void);
float INA226_WE_getBusPower(void);
void INA226_WE_startSingleMeasurement(void);
void INA226_WE_startSingleMeasurementNoWait(void);
_Bool INA226_WE_isBusy(void);
void INA226_WE_powerDown(void);
void INA226_WE_powerUp(void); 
void INA226_WE_waitUntilConversionCompleted(void);
void INA226_WE_setAlertPinActiveHigh(void);
void INA226_WE_enableAlertLatch(void);
void INA226_WE_enableConvReadyAlert(void);
void INA226_WE_setAlertType( alertType type, float limit);
void INA226_WE_readAndClearFlags(void);
uint8_t INA226_WE_getI2cErrorCode(void);



#endif // __INA226_H_


